/*
 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

#pragma once

#include <config.h>
#include <object/structures.h>

#ifdef CONFIG_VTX

struct EPTPDPTMapped_ret {
    ept_pml4e_t *pml4;      /*Z EPT一级页表线性地址 */
    ept_pml4e_t *pml4Slot;  /*Z EPT一级页表项线性地址 */
    exception_t status;
};
typedef struct EPTPDPTMapped_ret EPTPDPTMapped_ret_t;/*Z EPT一级页表项结果 */

struct EPTPageDirectoryMapped_ret {
    ept_pml4e_t *pml4;
    ept_pdpte_t *pdptSlot;
    exception_t status;
};
typedef struct EPTPageDirectoryMapped_ret EPTPageDirectoryMapped_ret_t;

struct EPTPageTableMapped_ret {
    ept_pml4e_t *pml4;
    ept_pde_t *pdSlot;
    exception_t status;
};
typedef struct EPTPageTableMapped_ret EPTPageTableMapped_ret_t;

struct findEPTForASID_ret {
    exception_t status;
    ept_pml4e_t *ept;   /*Z EPT一级页表线性地址 */
};
typedef struct findEPTForASID_ret findEPTForASID_ret_t;/*Z 查找EPT一级页表结果 */
/*Z 获取EPT二级页表的一级页表项。asid二级页表关联的ASID(PCID)，vptr该页表虚拟地址，pdpt其线性地址 */
EPTPDPTMapped_ret_t EPTPDPTMapped(asid_t asid, vptr_t vptr, ept_pdpte_t *pdpt);
EPTPageDirectoryMapped_ret_t EPTPageDirectoryMapped(asid_t asid, vptr_t vaddr, ept_pde_t *pd);
EPTPageTableMapped_ret_t EPTPageTableMapped(asid_t asid, vptr_t vaddr, ept_pte_t *pt);
findEPTForASID_ret_t findEPTForASID(asid_t asid);/*Z 查找ASID(PCID)对应的EPT一级页表线性地址 */
/*Z 清除EPT一级页表在ASID(PCID) pool中的映射项 */
void deleteEPTASID(asid_t asid, ept_pml4e_t *ept);
exception_t decodeX86EPTInvocation(word_t invLabel, word_t length, cptr_t cptr, cte_t *cte, cap_t cap,
                                   extra_caps_t excaps, word_t *buffer);
exception_t decodeX86EPTPDInvocation(word_t invLabel, word_t length, cte_t *cte, cap_t cap, extra_caps_t excaps,
                                     word_t *buffer);
exception_t decodeX86EPTPTInvocation(word_t invLabel, word_t length, cte_t *cte, cap_t cap, extra_caps_t excaps,
                                     word_t *buffer);
exception_t decodeX86EPTPageMap(word_t invLabel, word_t length, cte_t *cte, cap_t cap, extra_caps_t excaps,
                                word_t *buffer);
exception_t performX86EPTPageInvocationUnmap(cap_t cap, cte_t *ctSlot);
void unmapEPTPDPT(asid_t asid, vptr_t vaddr, ept_pdpte_t *pdpt);/*Z 清除EPT二级页表的一级页表项，清缓存。asid二级页表关联的ASID(PCID)，vptr该页表虚拟地址，pdpt其线性地址 */
void unmapEPTPageDirectory(asid_t asid, vptr_t vaddr, ept_pde_t *pd);/*Z 清除EPT三级页表的二级页表项，清缓存。asid三级页表关联的ASID(PCID)，vptr该页表虚拟地址，pdpt其线性地址 */
void unmapEPTPageTable(asid_t asid, vptr_t vaddr, ept_pte_t *pt);
void unmapEPTPage(vm_page_size_t page_size, asid_t asid, vptr_t vptr, void *pptr);/*Z 清除指定内存页的EPT页表映射 */

#endif /* CONFIG_VTX */

